#ifndef _TSNINSIGHT_H__
#define _TSNINSIGHT_H__

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>/*memcpy*/
#include <strings.h>/*bzero*/

#include <unistd.h>
#include <errno.h>

#include <arpa/inet.h>/*htons,ntohs*/

#include <endian.h>/*htobeXX,beXXtoh,htoleXX,leXXtoh*/
#include <sys/types.h>
#include <sys/socket.h>

#include <linux/if_ether.h>/*struct ethhdr*/
#include <linux/ip.h>/*struct iphdr*/
#include <sys/ioctl.h>
#include <net/if.h>
#include <netpacket/packet.h>



#define TSNINSIGHT_PORT 9099  //与TSNInsight通信时，约定的监听端口号
#define OPENSYNC_PORT   9089  //与OpesnSync通信时，约定的监听端口号
#define TSNLIGHT_PORT   8089  //与TSNLight通信时，约定的监听端口号


#define UDP_HEAD_LEN 	42

#define CONFIG_FILE "lib.cfg"

//TSNLight地址空间---寄存器地址的基地址
#define TSNLIGHT_REG_ADDR    0x00000000

//TSNLight地址空间---设备节点版本信息表的基地址
#define TSNLIGHT_NODE_VER_ADDR    0x00000100

//TSN交换机地址空间---只读地址
#define SWITCH_RO_START_ADDR  0x00200005  //只读地址的起始地址
#define SWITCH_RO_END_ADDR    0x00200014  //只读地址的结束地址

//TSN交换机地址空间---读写地址	
#define SWITCH_RW_PREVENT_BROADCAST_STORM_ADDR  0x63c09001  //防止广播风暴寄存器地址
#define SWITCH_RW_SCHEDULE_MODE_ADDR   0x63d00003           //调度模式寄存器地址
#define SWITCH_RW_FORWARD_MODE_ADDR    0x63d00007           //转发模式寄存器地址 (交换机还没配置这个地址)
	
#define SWITCH_RW_FLOWID_FORWARD_START_ADDR 0x63c00000 //FlowID转发表基地址
#define SWITCH_RW_FLOWID_FORWARD_END_ADDR   0x63c01fff //FlowID转发表结束地址


//OpenSync地址空间---寄存器地址的基地址
#define OPENSYNC_REG_ADDR    0x00000000

#define OPENSYNC_SYNC_PERIOD 0x00000004


//OpenSync地址空间---时间同步状态表的基地址
#define OPENSYNC_SYNC_STATE_ADDR    0x00000100



//文本最多1024行
#define MAX_LINES 1024

//文本每行最大256字节
#define LINE_LEN  256

#define LINE(x)   file.lines[x].line
#define LINE_CNT  file.line_cnt




//读写文本相关结构体
struct one_line {
	char line[LINE_LEN];
	int char_cnt;
};

//读写文本相关结构体
struct file_content {
	struct one_line lines[MAX_LINES];
	int line_cnt;
};

int tsninsight_get_cfgx_file(const char *filpath, const char *nam, char *val);

//TSNInsight初始化函数
int tsninsight_init();
int tsninsight_destroy();
void tsninsight_msg_sender(unsigned char *pkt,unsigned short pkt_len);
void generate_debug_pkt(unsigned char *pkt, unsigned short *len);


/**********************************北向应用需要访问的TSNLight地址空间的数据******************************************/

//TSNLight保存在寄存器地址中的数据
typedef struct
{
    unsigned int ver_num;      //版本号
    unsigned int link_ok;      //物理链路与逻辑链路是否一致（1是，0否）
    unsigned int syn_ok;       //是否时间同步（1是，0否）
    unsigned int node_num;     //当前网络节点数据
    unsigned int reserve;      //保留字段，有需要时再修改
}tsnlight_reg_data;

//TSNLight保存在设备节点版本信息表地址中的数据（单条）
typedef struct
{
    unsigned int node_mid; //设备节点mid
    unsigned int hcp_ver;  //HCP 逻辑版本号
    unsigned int os_ver;   //OS MAC 逻辑版本号
    unsigned int tss_ver;  //TSS 逻辑版本号
}node_ver_table;


//OpenSync保存在寄存器地址中的数据
typedef struct
{
    unsigned int protocol_type;  //Opensync软件协议类型
    unsigned int ver_num;        //Opensync软件版本号
    unsigned int ctrl_mode;      //Opensync软件运行模式（集中式0或分布式1）
    unsigned int master_mid;      //主时钟节点mid
    unsigned int sync_period;    //时间同步周期，单位ms
    unsigned int reserve;        //保留字段
}opensync_reg_data;


//OpenSync保存在时间同步状态表地址中的数据（单条）
typedef struct
{
    unsigned int node_mid;      //设备节点mid
    unsigned int sync_offset;   //与主时钟的同步偏差offset
}sync_state_table;


/*与REMOTE通信的tsmp报文头部*/
typedef struct
{
	unsigned char type; 	    /* 报文类型，固定为7 */
	unsigned char sub_type;  	/* 报文子类型，get_req、get_res、set_req和set_res */
}__attribute__((packed))remote_header;

/*报文结构*/
typedef struct
{
	remote_header header;      /* tsmp报文头部 */
	unsigned char data[0];     /* 报文数据 */
}__attribute__((packed))remote_manage_pkt;

typedef enum 
{
	REMOTE_GET_REQ = 0x01,   //查询请求
	REMOTE_GET_RES = 0x02,   //查询响应
	REMOTE_SET_REQ = 0x03, 	 //设置请求
	REMOTE_SET_RES = 0x04,   //设置响应
}REMOTE_MANAGE_SUB_TYPE;

typedef enum 
{
	REMOTE_TASK_SWITCH = 0x00,     //查询的控制实体为TSN交换机
	REMOTE_TASK_TSNLIGHT = 0x01,   //查询的控制实体为TSNLIGHT
	REMOTE_TASK_OPENSYNC = 0x02,   //查询的控制实体为OPENSYNC
}REMOTE_TASK_ID;

/*get_req报文数据结构定义*/
typedef struct
{
	remote_header header;      /* tsmp报文头部 */
	unsigned short mid;        /* 查询设备mid */
	unsigned short taskid;     /* 查询的控制实体，TSN交换机为0，TSNLight为1，OpenSync软件为2 */
    unsigned short num;        /* 数目 */
	unsigned int base_addr;    /* 基地址，网络序 */
}__attribute__((packed))remote_manage_get_req_pkt;

/*get_res报文数据结构定义*/
typedef struct
{
	remote_header header;      /* tsmp报文头部 */
	unsigned short mid;        /* 查询设备mid */
	unsigned short taskid;     /* 查询的控制实体，TSN交换机为0，TSNLight为1，OpenSync软件为2 */
    unsigned short num;        /* 数目 */
	unsigned int base_addr;    /* 基地址，网络序 */
	unsigned int value[0];     /* 查询响应数值，网络序 */
}__attribute__((packed))remote_manage_get_res_pkt;

/* set_req报文数据结构定义*/
typedef struct
{
	remote_header header;      /* tsmp报文头部 */
	unsigned short mid;        /* 设置设备mid */
	unsigned short taskid;     /* 设置的控制实体，TSN交换机为0，TSNLight为1，OpenSync软件为2 */
    unsigned short num;        /* 数目 */
	unsigned int base_addr;    /* 基地址，网络序 */
	unsigned int value[0];     /* 设置的数值，网络序 */
}__attribute__((packed))remote_manage_set_req_pkt;

/*set_res报文数据结构定义*/
typedef struct
{
	remote_header header;      /* tsmp报文头部 */
	unsigned short mid;        /* 设置设备节点 */
	unsigned short taskid;     /* 设置的控制实体，TSN交换机为0，TSNLight为1，OpenSync软件为2 */
    unsigned short num;        /* 数目 */
	unsigned int base_addr;    /* 基地址，网络序 */
}__attribute__((packed))remote_manage_set_res_pkt;



#endif


